package design.graduation.novelsystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import design.graduation.novelsystem.constant.Constant;
import design.graduation.novelsystem.mapper.CrawlerBookMapper;
import design.graduation.novelsystem.model.domian.BookContent;
import design.graduation.novelsystem.model.domian.CrawlerBook;
import design.graduation.novelsystem.model.domian.IncludeBook;
import design.graduation.novelsystem.model.dto.DataGridView;
import design.graduation.novelsystem.model.vo.CrawlerBookVo;
import design.graduation.novelsystem.service.BookContentService;
import design.graduation.novelsystem.service.CrawlerBookService;
import design.graduation.novelsystem.service.IncludeBookService;
import design.graduation.novelsystem.util.AnalyzeUtils;
import design.graduation.novelsystem.util.HttpClientUtils;
import design.graduation.novelsystem.util.ZipAndRarUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @author: 洪少尉
 * @Date: 2020/4/17 12:26
 * @Description: 
 */
@Service
public class CrawlerBookServiceImpl extends ServiceImpl<CrawlerBookMapper, CrawlerBook> implements CrawlerBookService{
	@Autowired
	private IncludeBookService includeBookService;
	@Autowired
	private BookContentService bookContentService;

	/**
	 * 用于爬取信息表单
	 *
	 * @param crawlerBookVo 查询条件
	 * @return DataGridView
	 */
	@Override
	public DataGridView queryAllCrawlerBook(CrawlerBookVo crawlerBookVo) {
		QueryWrapper<CrawlerBook> queryWrapper = new QueryWrapper<>();
		IPage<CrawlerBook> page = new Page<>(crawlerBookVo.getPage(),crawlerBookVo.getLimit());
		queryWrapper.eq(crawlerBookVo.getDownloadStatus() != null,CrawlerBook.COL_DOWNLOAD_STATUS,crawlerBookVo.getDownloadStatus())
				.like(StringUtils.isNotBlank(crawlerBookVo.getBookName()),CrawlerBook.COL_BOOK_NAME,crawlerBookVo.getBookName())
				.like(StringUtils.isNotBlank(crawlerBookVo.getAuthor()),CrawlerBook.COL_AUTHOR,crawlerBookVo.getAuthor())
				.ge(crawlerBookVo.getStartTime()!=null,CrawlerBook.COL_SAVE_TIME,crawlerBookVo.getStartTime())
				.le(crawlerBookVo.getEndTime()!=null,CrawlerBook.COL_SAVE_TIME,crawlerBookVo.getEndTime())
				.orderByDesc(CrawlerBook.COL_SAVE_TIME);
		this.baseMapper.selectPage(page,queryWrapper);
		return new DataGridView(page.getTotal(),page.getRecords());
	}

	/**
	 * 小说收录
	 *
	 * @param id 爬取的小说id
	 * @return boolean
	 */
	@Override
	public boolean includeBook(Integer id) {
		//1.下载小说
		//1.1查询小说下载地址
		CrawlerBook crawlerBook = this.baseMapper.selectById(id);
		String file =crawlerBook.getBookName()+crawlerBook.getDownloadUrl().substring(crawlerBook.getDownloadUrl().lastIndexOf("."));
		String url = crawlerBook.getDownloadUrl();
		url = url.replace(" ","%20");
		if(HttpClientUtils.download(url, Constant.DEFAULT_LOCAL_SAVE_ADDR,file)){
			try {
				//2.解压缩小说
				ZipAndRarUtils.unRarFile(Constant.DEFAULT_LOCAL_SAVE_ADDR+file,Constant.DEFAULT_UNRAR_ADDR);
				String bookSaveAddr = Constant.DEFAULT_UNRAR_ADDR+ crawlerBook.getBookName() + crawlerBook.getAuthor()+".txt";
				IncludeBook book = new IncludeBook(crawlerBook.getBookName(),crawlerBook.getAuthor(),
						crawlerBook.getPrimaryClassification(),crawlerBook.getSecondaryClassification(),
						crawlerBook.getTertiaryClassification(),crawlerBook.getIntroduction(),
						new Date(),new Date(),Constant.STATUS_FALSE,bookSaveAddr);
				//3.保存收录小说
				this.includeBookService.getBaseMapper().insert(book);
				//4.解析小说
				List<BookContent> bookContents = AnalyzeUtils.analyzeTxt(bookSaveAddr, book.getId(), crawlerBook.getBookName());
				//5.保存解析的小说
				this.bookContentService.saveBatch(bookContents);
				//6.更新爬取信息
				crawlerBook.setDownloadStatus(Constant.DOWNLOAD_SUCCESS);
				return this.updateById(crawlerBook);
			} catch (Exception e) {
				throw new RuntimeException("出现错误");
			}
		}
		return false;
	}
}
